package com.derbysoft.lowcostadapter.commons.repository.impl;

import com.derbysoft.common.paginater.Paginater;
import com.derbysoft.lowcostadapter.commons.model.TransactionLog;
import com.derbysoft.lowcostadapter.commons.repository.TransactionLogRepository;
import com.derbysoft.lowcostadapter.commons.utils.DateTimeUtils;
import com.derbysoft.lowcostadapter.web.action.admin.transactionlog.RequestLogCondition;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository("transactionLogRepository")
public class TransactionLogRepositoryImpl extends CommonService<TransactionLog> implements TransactionLogRepository {

    public static final String TIMESTAMP = "timestamp";
    public static final String TIME_SPAN = "timeSpan";

    @Override
    public Paginater findByCondition(final RequestLogCondition condition, Paginater paginater) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(TransactionLog.class).addOrder(Order.desc("id"));
        if (StringUtils.isNotBlank(condition.getHotelCode())) {
            detachedCriteria.add(Restrictions.like("hotels", condition.getHotelCode(), MatchMode.ANYWHERE));
        }
        if (StringUtils.isNotBlank(condition.getTaskId())) {
            detachedCriteria.add(Restrictions.eq("taskId", condition.getTaskId()));
        }
        if (condition.isHasError()) {
            detachedCriteria.add(Restrictions.eq("error", condition.isHasError()));
        }
        if (StringUtils.isNotBlank(condition.getStart()) && StringUtils.isNotBlank(condition.getEnd())) {
            detachedCriteria.add(Restrictions.ge(TIMESTAMP, DateTimeUtils.parse(condition.getStart())));
            detachedCriteria.add(Restrictions.le(TIMESTAMP, DateTimeUtils.parse(condition.getEnd())));
        } else if (StringUtils.isNotBlank(condition.getStart())) {
            detachedCriteria.add(Restrictions.ge(TIMESTAMP, DateTimeUtils.parse(condition.getStart())));
        } else if (StringUtils.isNotBlank(condition.getEnd())) {
            detachedCriteria.add(Restrictions.le(TIMESTAMP, DateTimeUtils.parse(condition.getEnd())));
        }
        if (condition.getMinSpentTime() != null && condition.getMaxSpentTime() != null) {
            detachedCriteria.add(Restrictions.ge(TIME_SPAN, condition.getMinSpentTime()));
            detachedCriteria.add(Restrictions.le(TIME_SPAN, condition.getMaxSpentTime()));
        } else if (condition.getMinSpentTime() != null) {
            detachedCriteria.add(Restrictions.ge(TIME_SPAN, condition.getMinSpentTime()));
        } else if (condition.getMaxSpentTime() != null) {
            detachedCriteria.add(Restrictions.le(TIME_SPAN, condition.getMaxSpentTime()));
        }
        return paginater(detachedCriteria, paginater);
    }

    @Override
    public TransactionLog findById(Long id) {
        return load(id);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void create(TransactionLog transactionLog) {
        super.commonRepository.save(transactionLog);
    }
}
